home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / news / inn1.000 / inn1.4sec-linux-src.tar / inn / expire / grephistory.c < prev    next >
C/C++ Source or Header  |  1993-01-29  |  6KB  |  310 lines

  1. /*  $Revision: 1.6 $
  2. **
  3. **  Get data from history database.
  4. */
  5. #include "configdata.h"
  6. #include <stdio.h>
  7. #include <ctype.h>
  8. #include <sys/types.h>
  9. #include <sys/stat.h>
  10. #if    defined(DO_NEED_TIME)
  11. #include <time.h>
  12. #endif    /* defined(DO_NEED_TIME) */
  13. #include <sys/time.h>
  14. #include <errno.h>
  15. #include "paths.h"
  16. #include "libinn.h"
  17. #include "clibrary.h"
  18. #include "dbz.h"
  19. #include "macros.h"
  20.  
  21.  
  22. /*
  23. **  Get the next filename from the history file.
  24. */
  25. STATIC BOOL
  26. GetName(F, buff, Againp)
  27.     register FILE    *F;
  28.     register char    *buff;
  29.     BOOL        *Againp;
  30. {
  31.     static char        SPOOL[] = _PATH_SPOOL;
  32.     register int    c;
  33.     register char    *p;
  34.  
  35.     /* Skip whitespace before filename. */
  36.     while ((c = getc(F)) == ' ')
  37.     continue;
  38.     if (c == EOF || c == '\n')
  39.     return FALSE;
  40.  
  41.     (void)strcpy(buff, SPOOL);
  42.     p = &buff[STRLEN(SPOOL)];
  43.     *p++ = '/';
  44.     *p++ = (char)c;
  45.     while ((c = getc(F)) != EOF && c != ' ' && c != '\n')
  46.     *p++ = (char)(c == '.' ? '/' : c);
  47.     *p = '\0';
  48.     *Againp = c != EOF && c != '\n';
  49.     return TRUE;
  50. }
  51.  
  52. /*
  53. **  Given a DBZ value, seek to the right spot.
  54. */
  55. STATIC BOOL
  56. HistorySeek(F, p)
  57.     register FILE    *F;
  58.     register char    *p;
  59. {
  60.     register char    *dest;
  61.     OFFSET_T        l;
  62.     register int    c;
  63.     register int    i;
  64.  
  65.     for (dest = (char *)&l, i = sizeof l; --i >= 0; )
  66.     *dest++ = *p++;
  67.     if (fseek(F, l, SEEK_SET) == -1) {
  68.     (void)fprintf(stderr, "Can't seek to %ld, %s\n", l, strerror(errno));
  69.     return FALSE;
  70.     }
  71.  
  72.     /* Move to the filename fields. */
  73.     for (i = 2; (c = getc(F)) != EOF && c != '\n'; )
  74.     if (c == HIS_FIELDSEP && --i == 0)
  75.         break;
  76.     if (c != HIS_FIELDSEP)
  77.     /* Could have only two fields (if expired) so don't complain now.
  78.      * (void)fprintf(stderr, "Bad text line for \"%s\", %s\n",
  79.      *    key, strerror(errno));
  80.      */
  81.     return FALSE;
  82.  
  83.     return TRUE;
  84. }
  85.  
  86.  
  87. /*
  88. **  Print the full line from the history file.
  89. */
  90. STATIC void
  91. FullLine(F, p)
  92.     register FILE    *F;
  93.     register char    *p;
  94. {
  95.     register char    *dest;
  96.     OFFSET_T        l;
  97.     register int    c;
  98.     register int    i;
  99.  
  100.     for (dest = (char *)&l, i = sizeof l; --i >= 0; )
  101.     *dest++ = *p++;
  102.     if (fseek(F, l, SEEK_SET) == -1) {
  103.     (void)fprintf(stderr, "Can't seek to %ld, %s\n", l, strerror(errno));
  104.     exit(1);
  105.     }
  106.  
  107.     while ((c = getc(F)) != EOF && c != '\n')
  108.     (void)putchar(c);
  109.     (void)putchar('\n');
  110. }
  111.  
  112.  
  113. /*
  114. **  Read stdin for list of Message-ID's, output list of ones we
  115. **  don't have.  Or, output list of files for ones we DO have.
  116. */
  117. STATIC void
  118. IhaveSendme(History, What)
  119.     STRING        History;
  120.     register char    What;
  121. {
  122.     register FILE    *F;
  123.     register char    *p;
  124.     register char    *q;
  125.     datum        key;
  126.     datum        value;
  127.     struct stat        Sb;
  128.     BOOL        More;
  129.     char        buff[BUFSIZ];
  130.     char        Name[SPOOLNAMEBUFF];
  131.  
  132.     /* Open history. */
  133.     if (dbminit(History) < 0) {
  134.     (void)fprintf(stderr, "Can't open history database, %s\n",
  135.         strerror(errno));
  136.     exit(1);
  137.     }
  138.     if ((F = fopen(History, "r")) == NULL) {
  139.     (void)fprintf(stderr, "Can't open \"%s\", %s\n",
  140.         History, strerror(errno));
  141.     exit(1);
  142.     }
  143.  
  144.     while (fgets(buff, sizeof buff, stdin) != NULL) {
  145.     for (p = buff; ISWHITE(*p); p++)
  146.         continue;
  147.     if (*p != '<')
  148.         continue;
  149.     for (q = p; *q && *q != '>' && !ISWHITE(*q); q++)
  150.         continue;
  151.     if (*q != '>')
  152.         continue;
  153.     *++q = '\0';
  154.     key.dptr = p;
  155.     key.dsize = q - key.dptr + 1;
  156.     value = dbzfetch(key);
  157.  
  158.     /* Ihave -- say if we want it, and continue. */
  159.     if (What == 'i') {
  160.         if (value.dptr == NULL)
  161.         (void)printf("%s\n", p);
  162.         continue;
  163.     }
  164.  
  165.     /* Sendme -- print a filename for the message. */
  166.     if (value.dptr == NULL)
  167.         /* Doesn't exist. */
  168.         continue;
  169.     if (HistorySeek(F, value.dptr))
  170.         while (GetName(F, Name, &More)) {
  171.         if (stat(Name, &Sb) >= 0) {
  172.             (void)printf("%s\n", Name);
  173.             break;
  174.         }
  175.         if (!More)
  176.             break;
  177.         }
  178.     }
  179. }
  180.  
  181.  
  182. /*
  183. **  Print a usage message and exit.
  184. */
  185. STATIC NORETURN
  186. Usage()
  187. {
  188.     (void)fprintf(stderr, "Usage: grephistory [flags] MessageID\n");
  189.     exit(1);
  190. }
  191.  
  192.  
  193. int
  194. main(ac, av)
  195.     int            ac;
  196.     char        *av[];
  197. {
  198.     register int    i;
  199.     register char    *p;
  200.     register FILE    *F;
  201.     STRING        History;
  202.     datum        key;
  203.     datum        value;
  204.     struct stat        Sb;
  205.     BOOL        More;
  206.     char        What;
  207.     char        Name[SPOOLNAMEBUFF];
  208.  
  209.     /* Set defaults. */
  210.     History = _PATH_HISTORY;
  211.     What = '?';
  212.  
  213.     /* Parse JCL. */
  214.     while ((i = getopt(ac, av, "f:eilnqs")) != EOF)
  215.     switch (i) {
  216.     default:
  217.         Usage();
  218.         /* NOTREACHED */
  219.     case 'f':
  220.         History = optarg;
  221.         break;
  222.     case 'e':
  223.     case 'i':
  224.     case 'l':
  225.     case 'n':
  226.     case 'q':
  227.     case 's':
  228.         if (What != '?') {
  229.         (void)fprintf(stderr, "Only one [eilnqs] flag allowed.\n");
  230.         exit(1);
  231.         }
  232.         What = (char)i;
  233.         break;
  234.     }
  235.     ac -= optind;
  236.     av += optind;
  237.  
  238.     /* Set operating mode. */
  239.     switch (What) {
  240.     case '?':
  241.     What = 'n';
  242.     break;
  243.     case 'i':
  244.     case 's':
  245.     IhaveSendme(History, What);
  246.     exit(0);
  247.     /* NOTREACHED */
  248.     }
  249.  
  250.     /* All modes other than -i -l want a Message-ID. */
  251.     if (ac != 1)
  252.     Usage();
  253.  
  254.     /* Open the history file, do the lookup. */
  255.     if (dbminit(History) < 0) {
  256.     (void)fprintf(stderr, "Can't open history database, %s\n",
  257.         strerror(errno));
  258.     exit(1);
  259.     }
  260.     key.dptr = av[0];
  261.     if (*key.dptr != '<') {
  262.     /* Add optional braces. */
  263.     key.dptr = NEW(char, 1 + strlen(av[0]) + 1);
  264.     (void)sprintf(key.dptr, "<%s>", av[0]);
  265.     }
  266.     for (p = key.dptr; *p; p++)
  267.     if (*p == HIS_FIELDSEP || *p == '\n')
  268.         *p = HIS_BADCHAR;
  269.     key.dsize = p - key.dptr + 1;
  270.     value = dbzfetch(key);
  271.  
  272.     /* Not found. */
  273.     if (value.dptr == NULL) {
  274.     if (What == 'n')
  275.         (void)fprintf(stderr, "Not found.\n");
  276.     exit(1);
  277.     }
  278.  
  279.     /* Simple case? */
  280.     if (What == 'q')
  281.     exit(0);
  282.  
  283.     /* Open the text file, go to the entry. */
  284.     if ((F = fopen(History, "r")) == NULL) {
  285.     (void)fprintf(stderr, "Can't open \"%s\", %s\n",
  286.         History, strerror(errno));
  287.     exit(1);
  288.     }
  289.     if (What == 'l') {
  290.     FullLine(F, value.dptr);
  291.     exit(0);
  292.     }
  293.  
  294.     /* Loop until we find an existing file. */
  295.     if (HistorySeek(F, value.dptr))
  296.     while (GetName(F, Name, &More)) {
  297.         if (stat(Name, &Sb) >= 0) {
  298.         (void)printf("%s\n", Name);
  299.         exit(0);
  300.         }
  301.         if (!More)
  302.         break;
  303.     }
  304.  
  305.     if (What == 'n')
  306.     (void)printf("/dev/null\n");
  307.     exit(0);
  308.     /* NOTREACHED */
  309. }
  310.